import type { AxiosError, AxiosInstance, AxiosRequestConfig } from "axios"
import axios from "axios"
import { clearUser, getToken, getUser, saveUser } from "./auth"
import router from "@/router"

export interface ApiResponse<T=any> {
    code: number,
    msg: string,
    data: T
}

// 刷新队列，避免并发多次刷新
let isRefreshing = false
let waitQueue: ((token?: string) => void)[] = []

const isDev = import.meta.env.MODE === 'development'

const http: AxiosInstance = axios.create({
    baseURL: isDev ? '/api' : '',
    timeout: 10_000
})

// 顶部创建一个专用的 axios 实例（不挂任何拦截器）
const refreshClient = axios.create({
  baseURL: isDev ? '/api' : '',
  timeout: 10000,
  withCredentials: true, // 让浏览器自动带 HttpOnly Cookie
})

// 带上 access_token
http.interceptors.request.use((config) => {
  const token = getToken()
  if (token) {
    config.headers = config.headers || {}
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
})

async function refreshAccessToken(): Promise<string> {
  // 用干净实例请求刷新接口，避免携带过期 Authorization
  const resp = await refreshClient.post<ApiResponse<{ token: string }>>('/api/auth/refresh', null)
  const token = resp.data.data?.token ?? (resp.data as any).token // 兼容两种返回结构
  if (!token) throw new Error('No token in refresh response')
  const u = getUser()
  if (u) saveUser({ ...u, token })
  return token
}

http.interceptors.response.use(
  (res) => res.data,
  async (error: AxiosError) => {
    const { response, config } = error
    if (response?.status === 401 && config) {
      // 已尝试刷新但失败，直接登出
      if ((config as any).__retried) {
        clearUser()
        router.replace({ name: 'Login', query: { redirect: router.currentRoute.value.fullPath } })
        return Promise.reject(error)
      }

      // 进入刷新流程
      if (!isRefreshing) {
        isRefreshing = true
        try {
          const newToken = await refreshAccessToken()
          // 唤醒队列
          waitQueue.forEach(fn => fn(newToken))
          waitQueue = []
          isRefreshing = false
        } catch (e) {
          waitQueue.forEach(fn => fn()) // 通知失败
          waitQueue = []
          isRefreshing = false
          clearUser()
          router.replace({ name: 'Login', query: { redirect: router.currentRoute.value.fullPath } })
          return Promise.reject(e)
        }
      }

      // 挂起当前请求，等刷新完成再重试
      return new Promise((resolve, reject) => {
        waitQueue.push((newToken?: string) => {
          if (!newToken) return reject(error)  // 刷新失败
          const cfg: AxiosRequestConfig = { ...config, headers: { ...(config.headers||{}), Authorization: `Bearer ${newToken}` } }
          ;(cfg as any).__retried = true
          resolve(http(cfg))
        })
      })
    }
    return Promise.reject(error)
  }
)


// http.interceptors.response.use(
//   (res) => res.data, 
//   (err) => Promise.reject(err)
// );

export default http 